package diploma.main;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Map;
import diploma.matrika.MatrikaParov.eTipRazdalje;
import diploma.substitucija.Substitucija;


public class IzpisStatistike
{
	public static double[] tabelaKazni = null;	
	
	public static boolean ENAKOPRAVNO_RACUNANJE_ZMOTE =  false;

	public static int ŠTEVILO_ITERACIJ_ENEGA_TESTA = 10;	
	
	public static int[] MaxNZaRazdalji = {8};	
	
	public static int[] TEKSTOVNE_PODMNOŽICE = {60,150,300};
	
	public static int ŠT_ITERACIJ_GENERACIJE_PODMNOŽICE = 50;
	
	public static void main(String[] args) throws FileNotFoundException, InterruptedException
	{
		initTabeloKazni();
		//1. naložimo besedilo in slovar
		//File slovar = new File("slovar-en.txt");File kombajn = new File("manjsi-sl-500.txt");
		File slovar = new File("slovar-sl.txt");File kombajn = new File("Test01.txt");
		TestSlovarBesedilo korpus = new TestSlovarBesedilo(slovar, kombajn);
		System.out.println("Slovar: "+slovar.getAbsolutePath()+", Kombajn:" + kombajn.getAbsolutePath());
		System.err.println("Konfiguracija testa:");
		System.err.println("MaxNZaRazdalji = " + Arrays.toString(MaxNZaRazdalji));
		System.err.println("ŠTEVILO_ITERACIJ_ENEGA_TESTA = " + ŠTEVILO_ITERACIJ_ENEGA_TESTA);
		System.err.println("TEKSTOVNE_PODMNOŽICE = " + Arrays.toString(TEKSTOVNE_PODMNOŽICE));
		System.err.println("ŠT_ITERACIJ_GENERACIJE_PODMNOŽICE = " + ŠT_ITERACIJ_GENERACIJE_PODMNOŽICE);
		System.err.println("FUNKCIJA za računanje zmote: " + (ENAKOPRAVNO_RACUNANJE_ZMOTE ? "kazenZaZmotoPravicna":"kazenZaZmoto")); 
		
		for(int numBesed :TEKSTOVNE_PODMNOŽICE)
		{
			testirajPodmnožico(numBesed, korpus);
		}
	}

	public static void testirajPodmnožico(int numBesed, TestSlovarBesedilo korpus)
	{
		System.out.println("**Test algoritma nad "+ numBesed + " besedami");
		System.out.println("#NumBesed|MaxN|razdalja|povprečen uspeh %");
		
		double rezultati[][] = new double[MaxNZaRazdalji.length][2];
		
		for(int iteracijaTesta = 0; iteracijaTesta < ŠT_ITERACIJ_GENERACIJE_PODMNOŽICE; iteracijaTesta++)
		{
			korpus.generirajNaključnoBesedilo(numBesed);
			int indexMaxN = 0;
			for(int maxN :MaxNZaRazdalji)
			{
				double rezEvk = testirajKonfiguracijo(ŠTEVILO_ITERACIJ_ENEGA_TESTA, maxN, eTipRazdalje.evklidska, korpus);
				double rezMan = testirajKonfiguracijo(ŠTEVILO_ITERACIJ_ENEGA_TESTA, maxN, eTipRazdalje.manhattan, korpus);
				rezultati[indexMaxN][0] += rezEvk;
				rezultati[indexMaxN][1] += rezMan;	
				indexMaxN++;
			}
		}
		//Izračunamo povprečje
		for(int i = 0; i < MaxNZaRazdalji.length; i++)
		{
			rezultati[i][0] = rezultati[i][0] / (double)ŠT_ITERACIJ_GENERACIJE_PODMNOŽICE;
			rezultati[i][1] = rezultati[i][1] / (double)ŠT_ITERACIJ_GENERACIJE_PODMNOŽICE;
			//Izpišemo rezultat tako, da lahko iz njega izrišemo stolpični graf
			System.out.println(String.format("%d|%d|%s|%f", numBesed, MaxNZaRazdalji[i], "evklidska", rezultati[i][0]*100));
			System.out.println(String.format("%d|%d|%s|%f", numBesed, MaxNZaRazdalji[i], "manhattan", rezultati[i][1]*100));
		}
	}	

	private static double testirajKonfiguracijo( 
			int štIteracij, 
			int maxN, 
			eTipRazdalje tipRazdalje,
			TestSlovarBesedilo korpus)
	{
		double success = 0;
		for(int i = 0; i < štIteracij; i++)
		{
			korpus.ponovnoPremešaj();
			final SolveCandidat2 solve = new SolveCandidat2(korpus.getMatSlovar(), korpus.getMatPremešanoBesedilo().clone(), tipRazdalje, maxN);
			solve.doSolve();
			
			double uspehr = 0;
			
			if(ENAKOPRAVNO_RACUNANJE_ZMOTE)
			{
				uspehr = 1 - kazenZaZmotoPravicna(solve.getSubstitucijoResitve(), korpus.subUporabljena);
			}
			else
			{				
				uspehr = 1 - kazenZaZmoto(solve.getSubstitucijoResitve(), korpus.subUporabljena);
			}
			success += uspehr;
		}
		return success/(double)štIteracij;
	}
	
	private static double kazenZaZmoto(Substitucija subRešitev, Substitucija subUporabljena)
	{
		double sestevekKazni = 0;
		for(int i = 0; i < Substitucija.tabela.length; i++)
		{
			char znak = Substitucija.tabela[i];
			if(subRešitev.substitute( subUporabljena.substitute(znak) ) != znak)
				sestevekKazni += tabelaKazni[i];
		}
		return sestevekKazni;
	}
	
	private static double kazenZaZmotoPravicna(Substitucija subRešitev, Substitucija subUporabljena)
	{
	
		double sestevekKazni = 0;
		double kazenskaTočka = 1.0 / Substitucija.tabela.length; 
		for(int i = 0; i < Substitucija.tabela.length; i++)
		{
			char znak = Substitucija.tabela[i];
			if(subRešitev.substitute( subUporabljena.substitute(znak) ) != znak)
				sestevekKazni += kazenskaTočka;
		}
		
		return sestevekKazni;
	}
	
	private static void initTabeloKazni()
	{
		Map<Character, Double> mapNorm = Normalizacija.getNormMap();
		tabelaKazni = new double[Substitucija.tabela.length]; //NA začetku so vse kazni enake 0
		for(Character key : mapNorm.keySet())
		{
			double kazen = mapNorm.get(key);
			int index = Substitucija.getIndex(key);
			tabelaKazni[index] = kazen;
		}
		
	}
	
}